package com.optimus.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author vperez
 */

public class ManejoArchivo {
    private static Logger logger = LoggerFactory.getLogger(ManejoArchivo.class);

    public static InputStream load(String fileName) throws ApplicationException{
        Object[] logParams = new Object[2];
        try {
            logParams[0]="iniciando...";
            logParams[1]=fileName;
            ManejoArchivo rl = new ManejoArchivo();
            logParams[0]="obteniendo recurso...";
            URL archivo =rl.getClass().getClassLoader().getResource(fileName);
            if (archivo==null){
                archivo = new URL("file:/"+fileName);
            }
            String filex = archivo.getFile();
            InputStream inputStream = null;
            if ("jar".equalsIgnoreCase(archivo.getProtocol() ) ){
                logParams[0]="recurso dentro de jar...";
                int px=filex.indexOf("!");
                String jarfile=filex.substring(0,px) ;
                String entry=filex.substring(px+2);
                JarFile jarFile = new JarFile(new File(new URI(jarfile) ) );
                ZipEntry zipEntry = new ZipEntry(entry);
                inputStream=jarFile.getInputStream(zipEntry);
            }else{
                logParams[0]="recurso es archivo...";
                inputStream=new FileInputStream(new File(archivo.toURI()));
            }
            return inputStream;
        } catch (URISyntaxException ex) {
            throw new ApplicationException("MSG1002",ex);
        } catch (IOException ex) {
            throw new ApplicationException("MSG1003",ex);
        }finally{
            logger.info("msg={}, file={}",logParams);
        }
    }
    /*
     * ref: http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath
     * author: http://stackoverflow.com/users/32978/will-glass
     */
    public static ArrayList<String> getClassNamesFromPackage(String packageName) throws IOException{
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL packageURL;
        ArrayList<String> names = new ArrayList<String>();;

        //packageName = packageName.replace(".", "/");
        packageURL = classLoader.getResource(packageName);

        if(packageURL.getProtocol().equals("jar")){
            String jarFileName;
            JarFile jf ;
            Enumeration<JarEntry> jarEntries;
            String entryName;

            // build jar file name, then loop through zipped entries
            jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
            jarFileName = jarFileName.substring(5,jarFileName.indexOf("!"));
            //System.out.println(">"+jarFileName);
            jf = new JarFile(jarFileName);
            jarEntries = jf.entries();
            while(jarEntries.hasMoreElements()){
                entryName = jarEntries.nextElement().getName();
                if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){
                    entryName = entryName.substring(packageName.length(),entryName.lastIndexOf('.'));
                    names.add(entryName);
                }
            }

        // loop through files in classpath
        }else{
            File folder = new File(packageURL.getFile());
            File[] contenuti = folder.listFiles();
            String entryName;
            for(File actual: contenuti){
                entryName = actual.getName();
                entryName = entryName.substring(0, entryName.lastIndexOf('.'));
                names.add(entryName);
            }
        }
        return names;
    }

}
